//
//  ViewController.m
//  Msg
//
//  Created by 蜂巢网络科技 on 2017/7/10.
//  Copyright © 2017年 fengchao. All rights reserved.
//

#import "ViewController.h"
#import "Person.h"
#import "UIImage+Category.h"
#import "NSObject+Category.h"
#import "Dog.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
   Dog *dog = [Dog readDog];
    
    NSLog(@"%@  %@",dog.name,dog.sex);
}

// 一、交换两个方法的实现，拦截系统自带的方法调用功能
- (void)test1
{
    
    [Person run];
    
    [Person study];
    
    // eg.  交换方法
    Method m1 = class_getClassMethod([Person class], @selector(run));
    Method m2 = class_getClassMethod([Person class], @selector(study));
    
    method_exchangeImplementations(m1, m2);
    
    [Person run];
    [Person study];
}


// 二、在分类中设置属性，给任何一个对象设置属性
- (void)test2
{
    NSObject *objc = [[NSObject alloc]init];
    objc.name = @"哥好帅啊";
    NSLog(@"%@",objc.name);
}


// 三、获得一个类的所有成员变量
// 案例1：所有成员变量
- (void)test3
{
    // 1. 测试
    unsigned int outCount = 0;
    Ivar *ivars = class_copyIvarList([Dog class], &outCount);

    // 遍历所有成员变量
    for (int i = 0; i < outCount; i++) {
        // 取出i位置对应的成员变量
        Ivar ivar = ivars[i];
        const char *name = ivar_getName(ivar);
        const char *type = ivar_getTypeEncoding(ivar);
        NSLog(@"成员变量名：%s 成员变量类型：%s",name,type);
    }
    // 注意释放内存！
    free(ivars);
}

// 案例2：利用runtime获取所有属性来重写归档解档方法
- (void)test4
{
    Dog *dog = [[Dog alloc] init];
    dog.name = @"Tom------------";
    dog.age = 20;
    dog.weight = 40;
    dog.sex = @"female";
    dog.color = [UIColor yellowColor];
    
    [Dog saveDog:dog];
}

//  字典转模型我们需要考虑三种特殊情况：
//  1.当字典的key和模型的属性匹配不上
//  2.模型中嵌套模型（模型属性是另外一个模型对象）
//  3.数组中装着模型（模型的属性是一个数组，数组中是一个个模型对象）
- (void)test5
{

}

@end
